home *** CD-ROM | disk | FTP | other *** search
- #APP
-
- | void bcopy(void *src, void *dst, size_t cnt)
- | handle overlap (both ways), odd/even alignment etc
- | ++jrb bammi@dsrgsun.ces.cwru.edu
- |
- | modified to use, whenever possible, unrolled loops
- | in both copy directions;
- | no check for an overlap anymore, but copying goes
- | up or down, depending on src-dst ordering;
- | all loops recoded as (double) dbra loops;
- | added entry point for
- | void *memmove(void *dest, const void *src, size_t cnt);
- | Michal Jaegermann ntomczak@vm.ucs.ualberta.ca
- |
- |
- .text
- .even
- .globl _bcopy
- .globl _lbcopy
- .globl _memmove
- _memmove:
- movl sp@(4),a1 | dst -> a1
- movl sp@(8),a0 | src -> a0
- jra L0
-
- _bcopy:
- _lbcopy:
- movl sp@(4),a0 | src -> a0
- movl sp@(8),a1 | dst -> a1
- L0:
- movl sp@(12),d0 | cnt -> d0
- jeq return | cnt == 0, nothing to do
- cmpl a1,a0 | which way to copy
- jeq return | same source and destination? we are done
- moveml d2-d4/a1,sp@- | save d2,d3,d4,a1(dst) - condition codes
- | are not affected
- smi d4 | d4 is set if we are going to copy down
- jpl L1
- addl d0,a0
- addl d0,a1
-
- L1:
- | check for odd src or dst
- movw a0,d1
- movw a1,d2
- eorb d1,d2
- btst #0,d2
- jne oddeven
- btst #0,d1 | do we have an extra byte?
- jeq setup
- btst #0,d4
- jeq upbyte
- movb a0@-,a1@-
- jra decrease
- upbyte:
- movb a0@+,a1@+
- decrease:
- subql #1,d0 | now even even
-
- setup:
- | if we are here we can unroll a copy loop
- movl d0,d2
- lsrl #5,d2 | how many times through a copy loop
- movl d2,d3 | get upper 16 bits of d2 into
- swap d3 | lower word of d3
-
- | calculate loop offset - it has to be word anyway
- movw d0,d1
- andw #0x1c,d1 | 4 bytes/copy 32 bytes max/iter
- lsrw #1,d1 | calc index into loop (each movl == 2bytes)
- negw d1 |
- addw #18,d1 | 16 + 2 bytes for jmp ext word - d1 == index
-
- btst #0,d4
- jeq eveneven
- | drop into another loop to copy down
- addw #(loop2 - loop1),d1
-
- eveneven: | may want long alignment for 020/030 etc
- jmp pc@(0,d1:w) | dive into a proper loop at appro spot
- loop1:
- movl a0@+,a1@+
- movl a0@+,a1@+
- movl a0@+,a1@+
- movl a0@+,a1@+
-
- movl a0@+,a1@+
- movl a0@+,a1@+
- movl a0@+,a1@+
- movl a0@+,a1@+
-
- dbra d2,loop1
- dbra d3,loop1
-
- btst #1,d0
- jeq L4
- movw a0@+,a1@+ | residual word
- L4: btst #0,d0
- jeq ret
- movb a0@,a1@ | residual byte
- ret:
- moveml sp@+,d2-d4/a1
- return:
- movl a1,d0 | memmove returns its destination
- rts
-
- loop2:
- movl a0@-,a1@-
- movl a0@-,a1@-
- movl a0@-,a1@-
- movl a0@-,a1@-
-
- movl a0@-,a1@-
- movl a0@-,a1@-
- movl a0@-,a1@-
- movl a0@-,a1@-
-
- dbra d2,loop2
- dbra d3,loop2
-
- btst #1,d0
- jeq L5
- movw a0@-,a1@- | residual word
- L5: btst #0,d0
- jeq ret
- movb a0@-,a1@- | residual byte
- jra ret
-
- oddeven:
- movl d0,d1
- swap d1
- btst #0,d4
- jne downbra
- jra upbra
- upcopy: | byte-by-byte forward
- movb a0@+,a1@+
- upbra:
- dbra d0,upcopy
- dbra d1,upcopy
- jra ret
-
- downcopy: | byte-by-byte backward
- movb a0@-,a1@-
- downbra:
- dbra d0,downcopy
- dbra d1,downcopy
- jra ret
-